﻿//#include<iostream>
//using namespace std;
//int main()
//{
//	cout << cin.good() << endl;
//	cout << cin.eof() << endl;
//	cout << cin.bad() << endl;
//	cout << cin.fail() << endl << endl;
//
//	// 输⼊⼀个字符或多个字符，cin读取失败，流状态被标记为failbit
//	int i = 0;
//	cin >> i;
//	cout << i << endl;
//	cout << cin.good() << endl;
//	cout << cin.eof() << endl;
//	cout << cin.bad() << endl;
//	cout << cin.fail() << endl << endl;
//
//	if (cin.fail())
//	{
//		// clear可以恢复流状态位goodbit
//		cin.clear();
//		// 我们还要把缓冲区中的多个字符都读出来，
//		// 读到数字停下来，否则再去cin>>i还是会失败
//		char ch = cin.peek();
//		while (!(ch >= '0' && ch <= '9'))
//		{
//			ch = cin.get();
//			cout << ch;
//			ch = cin.peek();
//		}
//		cout << endl;
//		cout << cin.good() << endl;
//		cout << cin.eof() << endl;
//		cout << cin.bad() << endl;
//		cout << cin.fail() << endl << endl;
//		cin >> i;
//		cout << i << endl;
//		return 0;
//	}
//}

//#include<iostream>
//#include<fstream>
//using namespace std;
//void func(ostream& os)
//{
//	os << "hello world";
//	os << "hello bit";
//	//"hello world"和"hello bit"进入缓冲区
//	system("pause");
//
//	//endl和"\n"不等价，endl不是单纯的换行，还负责刷新缓冲区
//	//遇到endl或flush，"hello world"和"hello bit"刷新缓冲区输出
//	//os << endl;
//	//os << flush;
//
//	//cin与ofs解绑
//	cin.tie(nullptr);
//
//	int i;
//	cin >> i;
//
//	os << "hello cat";
//	//"hello cat"进入缓冲区
//	system("pause");
//}
//int main()
//{
//	ofstream ofs("test.txt");
//
//	//unitbuf设置后，ofs每次写都直接刷新
//	//ofs << unitbuf;
// 
//	//cin绑定到ofs，cin进⾏读时，会刷新ofs的缓冲区
//	cin.tie(&ofs);
//
//	func(ofs);
//
//	return 0;
//}

//#include <iostream>
//using namespace std;
//
//int main()
//{
//	//在io需求⽐较⾼的地⽅，如部分⼤量输⼊的竞赛题中，加上以下⼏⾏代码可以提⾼C++IO效率
//    //并且建议⽤'\n'替代endl，因为endl会刷新缓冲区
//
//    //关闭标准 C++ 流是否与标准 C 流在每次输⼊/输出操作后同步。
//	ios_base::sync_with_stdio(false);
//
//	//关闭同步后，以下程序可能顺序为b a c
//	cout << "a\n";
//	printf("b\n");
//	cout << "c\n";
//
//	// 解绑cin和cout关联绑定的其他流
//	cin.tie(nullptr);
//	cout.tie(nullptr);
//
//	return 0;
//}

//#include<iostream>
//#include<fstream>
//#include<string>
//using namespace std;
//int main()
//{
//	int i = 0, j = 1;
//	//持续的输⼊，要结束需要输⼊Ctrl+Z换⾏，Ctrl+Z⽤于告诉
//	//程序输⼊已经完成，类似于在⽂件末尾添加⼀个标记。
//	//istream& operator>>(int i),>>运算符重载的返回值是istream对象，
//	//istream对象可以调⽤operator bool转换为bool值本质在底层是
//	//将cin的eofbit和failbit标志位设置了，cin调⽤operator bool函数
//	//语法逻辑上实现转换为bool值
//	while (cin >> i >> j)
//	{
//		cout << i << ":" << j << endl;
//	}
//	cout << cin.good() << endl;
//	cout << cin.eof() << endl;
//	cout << cin.bad() << endl;
//	cout << cin.fail() << endl << endl;
//
//	//流⼀旦发⽣错误就不能再⽤了，清理重置⼀下再能使⽤
//	cin.clear();
//
//	string s;
//	while (cin >> s)
//	{
//		cout << s << endl;
//	}
//
//	return 0;
//}

//#include <iostream>
//#include <fstream>
//#include <string>
//using namespace std;
//
//int main()
//{
//	//实现⼀个图⽚⽂件的复制，需要⽤⼆进制⽅式打开读写，
//	//第⼀个参数可以给⽂件的绝对路径
//	ifstream ifs("C:\\Users\\liuhu\\Desktop\\大头照.jpg",
//		ios_base::in | ios_base::binary);
//	ofstream ofs("C:\\Users\\liuhu\\Desktop\\大头照-copy.jpg",
//		ios_base::out | ios_base::binary);
//
//	int n = 0;
//	while (ifs && ofs)
//	{
//		char ch = ifs.get();
//		ofs << ch;
//		++n;
//	}
//	cout << n << endl;
//
//	return 0;
//}

//int main()
//{
//	ofstream ofs("test.txt");
//
//	//字符和字符串的写
//	ofs.put('x');
//	ofs.write("hello\nworld", 11);
//
//	//使⽤<<进⾏写
//	ofs << "22222222" << endl;
//	int x = 111;
//	double y = 1.11;
//	ofs << x << endl;
//	ofs << y << endl;
//	ofs.close();
//
//	//app和ate都是尾部追加，不同的是app不能移动⽂件指针，永远是在⽂件尾写
//	//ate可以移动⽂件指针，写到其他位置
//	//out和app被设置不会清空文件内容，out和ate被设置会清空文件内容
//	ofs.open("test.txt", ios_base::out | ios_base::app);
//	ofs << "1111111" << endl;
//	ofs.seekp(0, ios_base::beg);
//	ofs << x << " " << y << endl;
//	ofs.close();
//
//	ofs.open("test.txt", ios_base::out | ios_base::ate);
//	ofs << "1111111" << endl;
//	ofs.seekp(0, ios_base::beg);
//	ofs << x << " " << y << endl;
//	ofs.close();
//
//
//	//out和 out|trunc都会先把数据清掉，再写数据
//	ofs.open("test.txt", ios_base::out);
//	//ofs.open("test.txt", ios_base::out | ios_base::trunc);
//	ofs << "xxxx";
//	ofs.close();
//	return 0;
//}

//#include<iostream>
//#include<fstream>
//#include<string>
//using namespace std;
//
//class Date
//{
//	friend ostream& operator << (ostream& out, const Date& d);
//	friend istream& operator >> (istream& in, Date& d);
//public:
//	Date(int year = 1, int month = 1, int day = 1)
//		:_year(year)
//		, _month(month)
//		, _day(day)
//	{}
//private:
//	int _year;
//	int _month;
//	int _day;
//};
//
//istream& operator >> (istream& in, Date& d)
//{
//	in >> d._year >> d._month >> d._day;
//	return in;
//}
//
//ostream& operator << (ostream& out, const Date& d)
//{
//	out << d._year << " " << d._month << " " << d._day << endl;
//	return out;
//}
//
//struct ServerInfo
//{
//	// ⼆进制读写时，这⾥不能⽤string，否则写到⽂件中的是string中指向字符数组的指针
//	// 若string对象析构后再去⽂件中读取string对象，string中读到是⼀个野指针。
//	char _address[32];
//	//string _address;
//	int _port;
//	Date _date;
//};
//
//struct ConfigManager
//{
//public:
//	ConfigManager(const char* filename)
//		:_filename(filename)
//	{}
//
//	// ⼆进制写
//	// 直接将内存中存储的内容写入到文件中
//	void WriteBin(const ServerInfo& info)
//	{
//		ofstream ofs(_filename, ios_base::out | ios_base::binary);
//		ofs.write((const char*)&info, sizeof(info));
//	}
//
//	// ⼆进制读
//	// 将⽂件中的内容直接读到内存中
//	void ReadBin(ServerInfo& info)
//	{
//		ifstream ifs(_filename, ios_base::in | ios_base::binary);
//		ifs.read((char*)&info, sizeof(info));
//	}
//
//	//文本写
//	void WriteText(const ServerInfo& info)
//	{
//		ofstream ofs(_filename);
//		ofs << info._address << " " << info._port << " " << info._date;
//	}
//
//	//文本读
//	void ReadText(ServerInfo& info)
//	{
//		ifstream ifs(_filename);
//		ifs >> info._address >> info._port >> info._date;
//	}
//
//private:
//	string _filename; // 配置⽂件
//};
//
//void WriteBin()
//{
//	ServerInfo winfo = { "192.0.0.1111111111111111111111", 80, { 2025, 1, 10 }
//	};
//	//⼆进制写
//	ConfigManager cf_bin("test.bin");
//	cf_bin.WriteBin(winfo);
//}
//
//void ReadBin()
//{
//	//⼆进制读
//	ConfigManager cf_bin("test.bin");
//	ServerInfo rbinfo;
//	cf_bin.ReadBin(rbinfo);
//	cout << rbinfo._address << " " << rbinfo._port << " " << rbinfo._date <<
//		endl;
//}
//void WriteText()
//{
//	ServerInfo winfo = { "192.0.0.1", 80, { 2025, 1, 10 } };
//
//	//⽂本写
//	ConfigManager cf_text("test.txt");
//	cf_text.WriteText(winfo);
//}
//void ReadText()
//{
//	ConfigManager cf_text("test.txt");
//	ServerInfo rtinfo;
//	//文本读
//	cf_text.ReadText(rtinfo);
//	cout << rtinfo._address << " " << rtinfo._port << " " << rtinfo._date <<
//		endl;
//}
//
//int main()
//{
//	WriteBin();
//	ReadBin();
//
//	//WriteText();
//	//ReadText();
//
//	return 0;
//}

#include<iostream>
#include<sstream>
#include<string>
using namespace std;

class Date
{
	friend ostream& operator << (ostream& out, const Date& d);
	friend istream& operator >> (istream& in, Date& d);
public:
	Date(int year = 1, int month = 1, int day = 1)
		:_year(year)
		, _month(month)
		, _day(day)
	{}
private:
	int _year;
	int _month;
	int _day;
};

istream& operator >> (istream& in, Date& d)
{
	in >> d._year >> d._month >> d._day;
	return in;
}

ostream& operator << (ostream& out, const Date& d)
{
	out << d._year << " " << d._month << " " << d._day << endl;
	return out;
}

//int main()
//{
//	//将其他类型数据输出到stringIO流
//	int i = 123;
//	Date d = { 2025, 4, 10 };
//	ostringstream oss;
//	oss << i << endl;
//	oss << d << endl;
//	string s = oss.str();
//	cout << s << endl;
//
//	//将stringIO流中的数据输入到其他类型对象
//	istringstream iss("100 2025 9 9");
//	int j;
//	Date x;
//	iss >> j >> x;
//	cout << j << endl;
//	cout << x << endl;
//
//	int a = 1234;
//	int b = 5678;
//	string str;
//
//	//将⼀个整形变量转化为字符串，存储到string类对象中
//	stringstream ss;
//	ss << a << " " << b;
//	ss >> str;
//	//str = ss.str();
//	cout << str << endl;
//
//	cout << ss.fail() << endl;
//	cout << ss.bad() << endl;
//
//	//注意多次转换时，必须使⽤clear将上次转换状态清空掉
//	//stringstreams在转换结尾时(即最后⼀个转换后),会将其内部状态设置为badbit和failbit
//	//因此下⼀次转换是必须调⽤clear()将状态重置为goodbit才可以转换
//	//但是clear()不会将stringstreams底层字符串清空掉,str给⼀个空串可以清掉底层的字符串
//	ss.clear();
//	ss.str("");
//
//	double dd = 12.34;
//	ss << dd;
//	ss >> str;
//	cout << str << endl;
//	return 0;
//}

struct ChatInfo
{
	string _name; // 名字
	int _id; // id
	Date _date; // 时间
	string _msg; // 聊天信息
};

int main()
{
	// 结构信息序列化为字符串
	ChatInfo winfo = { "张三", 135246, { 2022, 4, 10 }, "晚上一起看电影吧" };
	ostringstream oss;
	oss << winfo._name << " " << winfo._id << " " << winfo._date << " " <<
		winfo._msg;
	string str = oss.str();
	cout << str << endl << endl;
	
	//字符串解析成结构信息
	ChatInfo rInfo;
	istringstream iss(str);
	iss >> rInfo._name >> rInfo._id >> rInfo._date >> rInfo._msg;
	cout << "-------------------------------------------------------" << endl;
	cout << "姓名：" << rInfo._name << "(" << rInfo._id << ") " << endl;
	cout << "时间：" << rInfo._date << endl;
	cout << rInfo._name << ":>" << rInfo._msg << endl;
	cout << "-------------------------------------------------------" << endl;

	return 0;
}

